package cn.edu.dlut.port.isp.bean.teach.simulation;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cn.edu.dlut.port.isp.repostitory.teach.ShipRepository;
import cn.edu.dlut.port.optiplan.elem.Ship;

/**
 *
 * @author tangguolei
 */
@Component
public class ConfInfoUtil {

    public static int GENERALCARGOSHIP = 1;
    public static int IMPORTBULKFREIGHTER = 2;
    public static int EXPORTBULKFREIGHTER = 3;
    public static int IMPORTOILCARRIER = 4;
    public static int EXPORTOILCARRIER = 5;
    public static int CONTAINERSHIP = 6;
    public static int BULKFREIGHTER = 7;
    public static int OILCARRIER = 8;
    
    
	@Autowired 
	private ShipRepository shipRepository;
	
	private static ConfInfoUtil ciUtil;
    
    @PostConstruct  
    public void init() { 
    	ciUtil = this; 
    	ciUtil.shipRepository = this.shipRepository; 
             } 

    public static ArrayList<double[]> getTideOf(int noPort) {
        ArrayList<double[]> tide = new ArrayList<>();
        String rootpath = Constants.DVSLPath + Constants.TIDEDIR;
        BufferedReader reader = getBufferedReader(rootpath);

        try {
            String it = reader.readLine();
            System.out.println(it.contains("id"));
            while ((it = reader.readLine()) != null) {
                String[] strs = it.split("\t");
                int num = strs.length;
                double tide0[] = new double[num];
                int portNo = Integer.parseInt(strs[0].trim());
                if (portNo == noPort) {
                    for (int i = 1; i < num; i++) {
                        if (!strs[i].trim().equals("-")) {
                            System.out.print(strs[i] + "\t");
                            tide0[i - 1] = Double.parseDouble(strs[i]);
                        } else {
                            tide0[i - 1] = Double.MIN_VALUE;
                        }
                    }
                    System.out.println("\n");
                    tide.add(tide0);
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(ConfInfoUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return tide;
    }

    public static ArrayList<PortBean> getPorts() {
        ArrayList<PortBean> ports = new ArrayList<>();
        JSONParser parser = new JSONParser();
        String rootPath = Constants.DVSLPath + Constants.SAMPLEDRIR;
        BufferedReader reader = ConfInfoUtil.getBufferedReader(rootPath);
        try {
            Object obj = parser.parse(reader);
            JSONObject jsonObject = (JSONObject) obj;
            String name = (String) jsonObject.get("name");
            System.out.println(name);
            JSONArray jsnPorts = (JSONArray) jsonObject.get("ports");
            System.out.println(jsnPorts.size());
            Iterator<JSONObject> iterator = jsnPorts.iterator();
            while (iterator.hasNext()) {
                PortBean port = new PortBean();
                ArrayList<BerthBean> berths = new ArrayList<>();
                JSONObject portJSON = (JSONObject) iterator.next();
                Number id = (Number) portJSON.get("id");
                port.setId(id.intValue());
                String portName = (String) portJSON.get("name");
                System.out.println(portName);
                port.setName(portName);
                JSONArray berthsJSON = (JSONArray) portJSON.get("berths");
                System.out.println(berthsJSON.size());
                Iterator<JSONObject> berthIterator = berthsJSON.iterator();
                while (berthIterator.hasNext()) {
                    JSONObject berthJSON = (JSONObject) berthIterator.next();
                    int cargoTypeInt = ((Number) berthJSON.get("cargoTypeID")).intValue();
                    String cargoType = (String) berthJSON.get("cargoType");
                    int tonnage = ((Number) berthJSON.get("tonnage")).intValue();
                    int number = ((Number) berthJSON.get("number")).intValue();
                    BerthBean berth = new BerthBean();
                    berth.setCargoTypeInt(cargoTypeInt);
                    berth.setCargoType(cargoType);
                    berth.setTonnage(tonnage);
                    berth.setNumber(number);
                    berths.add(berth);
                    System.out.print(berthJSON.get("cargoType") + "\t" + berthJSON.get("tonnage") + "\t" + berthJSON.get("number"));
                }
                port.setBerths(berths);
                double operationalDay = ((Number) portJSON.get("operationalDay")).doubleValue();
                int tideType = ((Number) portJSON.get("tideTypeID")).intValue();
                double tideRange = ((Number) portJSON.get("tideRange")).doubleValue();
                double averageWL = ((Number) portJSON.get("averageWL")).doubleValue();
                double desHWL = ((Number) portJSON.get("desHWL")).doubleValue();
                double desLWL = ((Number) portJSON.get("desLWL")).doubleValue();
                double extHWL = ((Number) portJSON.get("extHWL")).doubleValue();
                double extLWL = ((Number) portJSON.get("extLWL")).doubleValue();
                double waveHeight = ((Number) portJSON.get("waveHeight")).doubleValue();
                double wavePeriod = ((Number) portJSON.get("wavePeriod")).doubleValue();
                double waveAngle = ((Number) portJSON.get("waveAngle")).doubleValue();
                double crossCurrentV = ((Number) portJSON.get("crossCurrentV")).doubleValue();
                double longitudinalCurrentV = ((Number) portJSON.get("longitudinalCurrentV")).doubleValue();
                int depositState = ((Number) portJSON.get("despoit")).intValue();
                String portFilesStr = Constants.DVSLPath + portJSON.get("portFile");
                String geoFilesStr = Constants.DVSLPath + portJSON.get("geoFile");

                port.setOperationalDay(operationalDay);
                TideBean tide = new TideBean(tideType, tideRange, averageWL, desHWL, desLWL, extHWL, extLWL);
                port.setTideBean(tide);
                port.setWaveHeight(waveHeight);
                port.setWavePeriod(wavePeriod);
                port.setWaveAngle(waveAngle);
                port.setCrossCurrentV(crossCurrentV);
                port.setLongitudinalCurrentV(longitudinalCurrentV);
                port.setPortLayoutJPG(portFilesStr);
                port.setGeoJPG(geoFilesStr);
                port.setDepoistState(depositState);
                ports.add(port);
                System.out.println();
            }
        } catch (FileNotFoundException e) {
        } catch (IOException | ParseException ex) {
            Logger.getLogger(ConfInfoUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return ports;
    }

    public static String[] getPortNames() {
        StringBuilder names = new StringBuilder();
        JSONParser parser = new JSONParser();
        String rootPath = Constants.DVSLPath + Constants.SAMPLEDRIR;
        BufferedReader reader = ConfInfoUtil.getBufferedReader(rootPath);
        String tab = "\t";
        try {
            Object obj = parser.parse(reader);
            JSONObject jsonObject = (JSONObject) obj;
            String name = (String) jsonObject.get("name");
            System.out.println(name);
            JSONArray jsnPorts = (JSONArray) jsonObject.get("ports");
            System.out.println(jsnPorts.size());
            Iterator<JSONObject> iterator = jsnPorts.iterator();
            while (iterator.hasNext()) {
                JSONObject portJSON = (JSONObject) iterator.next();
                String portName = (String) portJSON.get("name");
                names.append(portName).append(tab);
            }
        } catch (FileNotFoundException e) {
        } catch (IOException | ParseException ex) {
            Logger.getLogger(ConfInfoUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return names.toString().split(tab);
    }

    public static Ship getDesignedShip(int typeInt, int tonnage, double v) {
        Ship ship = getDesignedShip(typeInt, tonnage);
        ship.setVelocity(v);
        return ship;
    }

    public static cn.edu.dlut.port.isp.bean.teach.ShipBean getShipFromShips(List<cn.edu.dlut.port.isp.bean.teach.ShipBean> list,int tonnage)
    {
    	 cn.edu.dlut.port.isp.bean.teach.ShipBean shipBean=new cn.edu.dlut.port.isp.bean.teach.ShipBean();
    	 for(cn.edu.dlut.port.isp.bean.teach.ShipBean s:list)
    	 {
   		 
    		 if(s.getTonnageDWT().trim().contains(tonnage+"(")||s.getTonnageDWT().trim().contains(tonnage+" ("))
     		{
     			 shipBean=s;
     		}else if((tonnage+"").equals(s.getTonnageDWT()))
     		{
     			 shipBean=s;
     		}
    	 }
    	 return shipBean;
    	
    }
    public static Ship getDesignedShip(int typeInt, int tonnage) {
    	 List<cn.edu.dlut.port.isp.bean.teach.ShipBean> shipBeans=ciUtil.shipRepository.findByCargoTypeIDAndTonnageDWTStartingWith(typeInt, tonnage+"");
    	 cn.edu.dlut.port.isp.bean.teach.ShipBean shipBean=getShipFromShips(shipBeans, tonnage);
    	 System.out.println(shipBean.toString());
    	 Ship ship=new Ship();
         ship.setTypeInt(typeInt);
         ship.setType(Ship.getTypeStringOf(typeInt));
         ship.setTypeDetail(Ship.getDetailTypeStringOf(typeInt));
         ship.setTonnage(tonnage);
         ship.setLength(shipBean.getL());
         ship.setWidth(shipBean.getB());
         ship.setDepth(shipBean.getH());
         ship.setDraft(Double.parseDouble(shipBean.getT()));
         ship.setCargoesPerShip(shipBean.getAve_cps());
         ship.setEfficiencyLULPerShip(Double.parseDouble(shipBean.getAvr_he()));
         ship.setVelocity(shipBean.getV());
        return ship;
    }

   /* public static Ship getDesignedShip(int typeInt, int tonnage) {
        String rootpath = Constants.DVSLPath;
        Ship ship = new Ship();
        switch (typeInt) {
            case 1:
                rootpath += Constants.GENERALCARGODS;
                break;
            case 2:
                rootpath += Constants.IMPORTBULKFREIGHTERDS;
                break;
            case 3:
                rootpath += Constants.EXPORTBULKFREIGHTERDS;
                break;
            case 4:
                rootpath += Constants.IMPORTOILCARRIERDS;
                break;
            case 5:
                rootpath += Constants.EXPORTOILCARRIERDS;
                break;
            case 6:
                rootpath += Constants.CONTAINERCARRIERDS;
                break;
            case 7:
                rootpath += Constants.IMPORTBULKFREIGHTERDS;
                break;
            case 8:
                rootpath += Constants.IMPORTOILCARRIERDS;
                break;
            default:
                throw (new NoSuchElementException());
        }
        try {
            BufferedReader reader = ConfInfoUtil.getBufferedReader(rootpath);
            String line;
            while ((line = reader.readLine()) != null) {
                if (!line.contains("type")) {
                    String[] shipAttrs = line.split("\t");
                    String tmp = shipAttrs[1].trim();
                    int idxOfbracket = tmp.indexOf("(");
                    int ton = Integer.parseInt(idxOfbracket < 0 ? tmp : (tmp.substring(0, idxOfbracket)).trim());
                    if (ton == tonnage) {
                        ship.setTypeInt(typeInt);
                        ship.setType(Ship.getTypeStringOf(typeInt));
                        ship.setTypeDetail(Ship.getDetailTypeStringOf(typeInt));
                        ship.setTonnage(ton);
                        ship.setLength(Double.parseDouble(shipAttrs[2]));
                        ship.setWidth(Double.parseDouble(shipAttrs[3]));
                        ship.setDepth(Double.parseDouble(shipAttrs[4]));
                        ship.setDraft(Double.parseDouble(shipAttrs[5]));
                        ship.setCargoesPerShip(Double.parseDouble(shipAttrs[11]));
                        ship.setEfficiencyLULPerShip(Double.parseDouble(shipAttrs[7]));
                        ship.setVelocity(Double.parseDouble(shipAttrs[12]));
                    }
                }
            }

        } catch (IOException ex) {
        }
        return ship;
    }*/

    @SuppressWarnings("CallToThreadDumpStack")
    public static PortBean getPortOf(int noPort) {
        PortBean port = new PortBean();
        ArrayList<BerthBean> berths = new ArrayList<>();
        JSONParser parser = new JSONParser();
        String rootPath = Constants.DVSLPath + Constants.SAMPLEDRIR;
        BufferedReader reader = ConfInfoUtil.getBufferedReader(rootPath);
        try {
            Object obj = parser.parse(reader);
            JSONObject jsonObject = (JSONObject) obj;
            String name = (String) jsonObject.get("name");
            System.out.println(name);
            JSONArray ports = (JSONArray) jsonObject.get("ports");
            System.out.println(ports.size());
            Iterator<JSONObject> iterator = ports.iterator();
            while (iterator.hasNext()) {
                JSONObject portJSON = (JSONObject) iterator.next();
                Number id = (Number) portJSON.get("id");
                if (id.intValue() == noPort) {
                    port.setId(noPort);
                    port.setName((String) portJSON.get("name"));
                    System.out.println(portJSON.get("name"));
                    JSONArray berthsJSON = (JSONArray) portJSON.get("berths");
                    System.out.println(berthsJSON.size());
                    Iterator<JSONObject> berthIterator = berthsJSON.iterator();
                    while (berthIterator.hasNext()) {
                        JSONObject berthJSON = (JSONObject) berthIterator.next();
                        int cargoTypeInt = ((Number) berthJSON.get("cargoTypeID")).intValue();
                        String cargoType = (String) berthJSON.get("cargoType");
                        int tonnage = ((Number) berthJSON.get("tonnage")).intValue();
                        int number = ((Number) berthJSON.get("number")).intValue();
                        BerthBean berth = new BerthBean();
                        berth.setCargoTypeInt(cargoTypeInt);
                        berth.setCargoType(cargoType);
                        berth.setTonnage(tonnage);
                        berth.setNumber(number);
                        berths.add(berth);
                        System.out.print(berthJSON.get("cargoType") + "\t" + berthJSON.get("tonnage") + "\t" + berthJSON.get("number"));
                    }
                    port.setBerths(berths);
                    double operationalDay = ((Number) portJSON.get("operationalDay")).doubleValue();
                    int tideType = ((Number) portJSON.get("tideTypeID")).intValue();
                    double tideRange = ((Number) portJSON.get("tideRange")).doubleValue();
                    double averageWL = ((Number) portJSON.get("averageWL")).doubleValue();
                    double desHWL = ((Number) portJSON.get("desHWL")).doubleValue();
                    double desLWL = ((Number) portJSON.get("desLWL")).doubleValue();
                    double extHWL = ((Number) portJSON.get("extHWL")).doubleValue();
                    double extLWL = ((Number) portJSON.get("extLWL")).doubleValue();
                    double waveHeight = ((Number) portJSON.get("waveHeight")).doubleValue();
                    double wavePeriod = ((Number) portJSON.get("wavePeriod")).doubleValue();
                    double waveAngle = ((Number) portJSON.get("waveAngle")).doubleValue();
                    double crossCurrentV = ((Number) portJSON.get("crossCurrentV")).doubleValue();
                    double longitudinalCurrentV = ((Number) portJSON.get("longitudinalCurrentV")).doubleValue();
                    int depositState = ((Number) portJSON.get("despoit")).intValue();
                    String portFilesStr = Constants.DVSLPath + portJSON.get("portFile");
                    String geoFilesStr = Constants.DVSLPath + portJSON.get("geoFile");
                    port.setOperationalDay(operationalDay);
                    TideBean tide = new TideBean(tideType, tideRange, averageWL, desHWL, desLWL, extHWL, extLWL);
                    port.setTideBean(tide);
                    port.setWaveHeight(waveHeight);
                    port.setWavePeriod(wavePeriod);
                    port.setWaveAngle(waveAngle);
                    port.setCrossCurrentV(crossCurrentV);
                    port.setLongitudinalCurrentV(longitudinalCurrentV);
                    port.setPortLayoutJPG(portFilesStr);
                    port.setGeoJPG(geoFilesStr);
                    port.setDepoistState(depositState);
                    System.out.println();
                    break;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException | ParseException ex) {
            Logger.getLogger(ConfInfoUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return port;
    }

    public static ArrayList<BerthBean> getBerths(int noOf) {
        ArrayList<BerthBean> berths = new ArrayList<>();
        String rootpath = Constants.DVSLPath + Constants.PORTSDIRS;
        BufferedReader reader = getBufferedReader(rootpath);
        try {
            String it;
            while ((it = reader.readLine()) != null) {
                if (!it.contains("port")) {
                    String[] shipAttrs = it.split("    ");

                    String tmp = shipAttrs[0].trim();
                    int no = Integer.parseInt(tmp);
                    if (no == noOf) {
                        int cargoType = Integer.parseInt(shipAttrs[1].trim());
                        int tonnage = Integer.parseInt(shipAttrs[2].trim());
                        int number = Integer.parseInt(shipAttrs[3].trim());
                        BerthBean berth = new BerthBean();
                        berth.setCargoTypeInt(cargoType);
                        berth.setCargoType(cargoType);
                        berth.setTonnage(tonnage);
                        berth.setNumber(number);
                        berths.add(berth);
                    }
                }
            }

        } catch (IOException ex) {
            Logger.getLogger(ConfInfoUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return berths;
    }

    public static ShipBean getShipBy(int typeInt, int tonnage) {
        String rootpath = Constants.DVSLPath;
        switch (typeInt) {
            case 1:
                rootpath += Constants.GENERALCARGODS;
                break;
            case 2:
                rootpath += Constants.IMPORTBULKFREIGHTERDS;
                break;
            case 3:
                rootpath += Constants.EXPORTBULKFREIGHTERDS;
                break;
            case 4:
                rootpath += Constants.IMPORTOILCARRIERDS;
                break;
            case 5:
                rootpath += Constants.EXPORTOILCARRIERDS;
                break;
            case 6:
                rootpath += Constants.CONTAINERCARRIERDS;
                break;
            case 7:
                rootpath += Constants.IMPORTBULKFREIGHTERDS;
                break;
            case 8:
                rootpath += Constants.IMPORTOILCARRIERDS;
                break;
            default:
                throw (new NoSuchElementException());
        }
        BufferedReader reader = getBufferedReader(rootpath);

        ShipBean ship = new ShipBean();
        try {
            String it;
            while ((it = reader.readLine()) != null) {
                if (!it.contains("type")) {
                    System.out.println(it);
                    String[] shipAttrs = it.split("\t");
                    String tmp = shipAttrs[1].trim();
                    int idxOfbracket = tmp.indexOf("(");
                    int ton = Integer.parseInt(idxOfbracket < 0 ? tmp : (tmp.substring(0, idxOfbracket)).trim());
                    System.out.println(tmp + "/t" + ton + "FT!");
                    if (ton == tonnage) {
                        ship.setTypeInt(typeInt);
                        //ship.setType(ship.getTypeStringOf(typeInt));
                        //ship.setTypeDetail(ship.getDetailTypeStringOf(typeInt));
                        ship.setTonnage(ton);
                        ship.setLength(Double.parseDouble(shipAttrs[2]));
                        ship.setWidth(Double.parseDouble(shipAttrs[3]));
                        ship.setDepth(Double.parseDouble(shipAttrs[4]));
                        ship.setDraft(Double.parseDouble(shipAttrs[5]));
                        ship.setCargoesPerShip(Double.parseDouble(shipAttrs[11]));
                        ship.setEfficiencyLULPerShip(Double.parseDouble(shipAttrs[7]));
                        ship.setVelocity(Double.parseDouble(shipAttrs[12]));
                    }
                }
            }

        } catch (IOException ex) {
            Logger.getLogger(ConfInfoUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return ship;
    }

    public static BufferedReader getBufferedReader(String rootpath) {
        BufferedReader reader = null;
        try {
            System.out.println(rootpath);
            InputStream is = Resource.class.getResourceAsStream(rootpath);
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));

        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(ConfInfoUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return reader;
    }

    public static String getJSON() {
        String rootPath = Constants.DVSLPath + Constants.SAMPLEDRIR;
        BufferedReader reader = getBufferedReader(rootPath);
        StringBuilder string = new StringBuilder();
        String jsonStr = "";
        try {
            String it;
            while ((it = reader.readLine()) != null) {
                string.append(it);
            }
            jsonStr = new String(string.toString().getBytes("UTF-8"), "UTF-8");
            System.out.println(jsonStr);
        } catch (IOException ex) {
            Logger.getLogger(ConfInfoUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        return jsonStr;
    }

    public static boolean updateContent(String name, String content, boolean append) {
        boolean res = true;
        String path = Constants.DVSLPath + name;
        File file = new File(path);
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            FileWriter writer = new FileWriter(file, append);
            if (append) {
                content = System.getProperty("line.separator") + content;
            }
            writer.write(content);
            writer.flush();
            writer.close();
        } catch (IOException ex) {
            res = false;
            ex.printStackTrace();
        }
        return res;
    }

    public static void main(String args[]) {
        ShipBean ship = ConfInfoUtil.getShipBy(1, 15000);
        System.out.println(ship.getDepth());

        ConfInfoUtil.updateContent("record.dat", "2018-03-24 08:00:00", true);
    }
}
